﻿
Imports std
Imports xmlctrl
Imports xmlparser
Imports usshare

Public Module api

    Private serverAddress As String = Nothing
#If RETIRED Then
    Private xmlparserPool As xmlparserPoolDefinition
#End If

    Public Sub initial(ByVal serverAddress As String)
        copy(api.serverAddress, serverAddress)
    End Sub

    Private Function findChildSection(ByVal root As xmlcontrol, ByVal tag As String) As list(Of xmlcontrol).iterator
        If Not root Is Nothing Then
            Dim it As list(Of xmlcontrol).iterator = Nothing
            it = root.children().begin()
            While it <> root.children().end()
                If strsame((+it).tag, tag, False) Then
                    Exit While
                End If
                it += 1
            End While

            Return it
        Else
            Return Nothing
        End If
    End Function

    Private Function findResult(ByVal root As xmlcontrol) As list(Of xmlcontrol).iterator
        Return findChildSection(root, sharedResponse.result)
    End Function

#If RETIRED Then
    Private Function request(ByVal address As String, ByRef response As String, ByRef root As xmlcontrol) As Boolean
        If readHttpWeb(address, response) Then
            Dim parser As parser = Nothing
            Dim index As Int64
            If xmlparserPool.getfree(index, parser) Then
                Dim rst As Boolean = False
                rst = parser.parse(response, root)
                If Not rst Then
                    raiseError("cannot parse response, ignore request. " + display(response) _
                               , errorHandle.errorType.warning)
                ElseIf root Is Nothing Then
                    raiseError("parse successfully, but did not return root node. " + strleft(response, 64) + "..." _
                               , errorHandle.errorType.warning)
                End If

                xmlparserPool.release(index)
                Return rst AndAlso Not root Is Nothing
            Else
                raiseError("cannot parse response, ignore request. " + display(response) _
                           , errorHandle.errorType.warning)
                Return False
            End If
        Else
            raiseError("cannot get http response from address " + address, errorHandle.errorType.warning)
            Return False
        End If
    End Function
#End If

    Public Function submit(ByVal key As String, ByVal url As String, ByRef shorturl As String _
                           , Optional ByRef submitResult As submitResult = submitResult.success) As Boolean
        debugassert(Not serverAddress Is Nothing, "should set serverAddress before use this submit function.")
        Return submit(serverAddress, key, url, shorturl, submitResult)
    End Function

    Private Function findSubmitRedirector(ByVal root As xmlcontrol) As list(Of xmlcontrol).iterator
        Return findChildSection(root, submitResponse.redirector)
    End Function

    Public Function submit(ByVal serverAddress As String, ByVal key As String, ByVal url As String _
                           , ByRef shorturl As String _
                           , Optional ByRef submitResult As submitResult = submitResult.success) As Boolean
        Dim response As String = Nothing
        Dim root As xmlcontrol = Nothing
        'do not need to special treat empty key input, as xmlapi can handle it
#If RETIRED Then
        If Not request(serverAddress + network.pathSeperator _
                       + urlUtils.combineQuery(query.url, url, query.key, key _
                                            , query.action, actionVerbs(action.submit)) _
                     , response, root) Then
#End If
        If Not readHttpXml(serverAddress, response, root _
                           , query.url, url, query.key, key, query.action, actionVerbs(action.submit)) Then
            'do not need messagebox here, readHttpWeb will handle it
            If errorHandle.mode = errorHandle.displayMode.console Then
                raiseError("cannot get valid response from server " + serverAddress, errorHandle.errorType.warning)
            End If
            Return False
        Else
            Dim it As list(Of xmlcontrol).iterator = Nothing
            it = findResult(root)

            If Not it Is Nothing AndAlso it <> root.children().end() Then
                If strsame((+it).text, submitResponse.success, False) Then
                    submitResult = submitResult.success
                    Dim it2 As list(Of xmlcontrol).iterator = Nothing
                    it2 = findSubmitRedirector(+it)

                    If Not it2 Is Nothing AndAlso it2 <> (+it).children().end() Then
                        copy(shorturl, Convert.ToString((+it2).text))
                        Return True
                    Else
                        raiseError("cannot find " + submitResponse.redirector + " section from response. " _
                                    + display(response), errorHandle.errorType.warning)
                        Return False
                    End If
                ElseIf strsame((+it).text, submitResponse.existingKey, False) Then
                    submitResult = submitResult.existingKey
                    Return False
                ElseIf strsame((+it).text, submitResponse.internalError, False) Then
                    submitResult = submitResult.internalError
                    Return False
                ElseIf strsame((+it).text, submitResponse.invalidKey, False) Then
                    submitResult = submitResult.invalidKey
                    Return False
                Else
                    raiseError("caught unknown result respone. " + display(response), errorHandle.errorType.warning)
                    submitResult = submitResult.unknown
                    Return False
                End If
            Else
                raiseError("cannot find " + sharedResponse.result + " section from response. " _
                           + display(response), errorHandle.errorType.warning)
                Return False
            End If
        End If
    End Function

    Public Function preview(ByVal key As String, ByRef url As String) As Boolean
        Return preview(serverAddress, key, url)
    End Function

    Private Function findPreviewDestination(ByVal root As xmlcontrol) As list(Of xmlcontrol).iterator
        Return findChildSection(root, previewResponse.destination)
    End Function

    Public Function preview(ByVal serverAddress As String, ByVal key As String, ByRef url As String) As Boolean
        Dim response As String = Nothing
        Dim root As xmlcontrol = Nothing
#If RETIRED Then
        If Not request(serverAddress + network.pathSeperator _
                        + urlUtils.combineQuery(query.key, key, query.action, actionVerbs(action.preview)) _
                        , response, root) Then
#End If
        If Not readHttpXml(serverAddress, response, root _
                           , query.key, key, query.action, actionVerbs(action.preview)) Then
            raiseError("cannot get valid response from server " + serverAddress, errorHandle.errorType.warning)
            Return False
        Else
            Dim it As list(Of xmlcontrol).iterator = Nothing
            it = findResult(root)

            If Not it Is Nothing AndAlso it <> root.children().end() Then
                If strsame((+it).text, previewResponse.success, False) Then
                    Dim it2 As list(Of xmlcontrol).iterator = Nothing
                    it2 = findPreviewDestination(+it)

                    If Not it2 Is Nothing AndAlso it2 <> (+it).children().end() Then
                        copy(url, Convert.ToString((+it2).text))
                        Return True
                    Else
                        raiseError("cannot find " + previewResponse.destination + " section from response." _
                                    , errorHandle.errorType.warning)
                        Return False
                    End If
                ElseIf strsame((+it).text, previewResponse.fail, False) Then
                    Return False
                Else
                    raiseError("caught unknown result response. " + display(response), errorHandle.errorType.warning)
                    Return False
                End If
            Else
                raiseError("cannot find " + sharedResponse.result + " section from response. " _
                           + display(response), errorHandle.errorType.warning)
                Return False
            End If
        End If
    End Function

    Public Function urlkeys(ByVal url As String, ByRef keys As [set](Of String)) As Boolean
        Return urlkeys(serverAddress, url, keys)
    End Function

    Public Function urlkeys(ByVal serverAddress As String, ByVal url As String _
                            , ByRef keys As [set](Of String)) As Boolean
        Dim response As String = Nothing
        Dim root As xmlcontrol = Nothing
#If RETIRED Then
        If Not request(serverAddress + network.pathSeperator _
                        + urlUtils.combineQuery(query.url, url, query.action, actionVerbs(action.urlKeyMapping)) _
                        , response, root) Then
#End If
        If Not readHttpXml(serverAddress, response, root _
                           , query.url, url, query.action, actionVerbs(action.urlkeys)) Then
            raiseError("cannot get valid response from server " + serverAddress, errorHandle.errorType.warning)
            Return False
        Else
            Dim it As list(Of xmlcontrol).iterator = Nothing
            it = findResult(root)

            If Not it Is Nothing AndAlso it <> root.children().end() Then
                If strsame((+it).text, urlkeysResponse.success, False) Then
                    Dim it2 As list(Of xmlcontrol).iterator = Nothing

                    If keys Is Nothing Then
                        keys = New [set](Of String)()
                    Else
                        keys.clear()
                    End If
                    it2 = (+it).children().begin()
                    While it2 <> (+it).children().end()
                        If strsame((+it2).tag, urlkeysResponse.key, False) Then
                            keys.insert((+it2).text)
                        End If
                        it2 += 1
                    End While

                    Return keys.size() > 0
                ElseIf strsame((+it).text, urlkeysResponse.fail, False) Then
                    Return False
                Else
                    raiseError("caught unknown result response. " + display(response), errorHandle.errorType.warning)
                    Return False
                End If
            Else
                raiseError("cannot find " + sharedResponse.result + " section from response. " _
                           + display(response), errorHandle.errorType.warning)
                Return False
            End If
        End If
    End Function

    Public Function have(ByVal url As String) As Boolean
        Return have(serverAddress, url)
    End Function

    Public Function have(ByVal serverAddress As String, ByVal url As String) As Boolean
        Dim response As String = Nothing
        Dim root As xmlcontrol = Nothing
#If RETIRED Then
        If Not request(serverAddress + network.pathSeperator _
                        + urlUtils.combineQuery(query.url, url, query.action, actionVerbs(action.have)) _
                        , response, root) Then
#End If
        If Not readHttpXml(serverAddress, response, root _
                           , query.url, url, query.action, actionVerbs(action.have)) Then
            raiseError("cannot get valid response from server " + serverAddress, errorHandle.errorType.warning)
            Return False
        Else
            Dim it As list(Of xmlcontrol).iterator = Nothing
            it = findResult(root)

            If Not it Is Nothing AndAlso it <> root.children().end() Then
                If strsame((+it).text, urlkeysResponse.success, False) Then
                    Return True
                ElseIf strsame((+it).text, urlkeysResponse.fail, False) Then
                    Return False
                Else
                    raiseError("caught unknown result response. " + display(response), errorHandle.errorType.warning)
                    Return False
                End If
            End If
        End If
    End Function

#If RETIRED Then
    Sub New()
        xmlparserPool = New xmlparserPoolDefinition()
    End Sub
#End If

    Public Sub unittest()
        'this seems useless now, as have a usapi application to do so.
    End Sub
End Module
